﻿
Imports System.Text

Public Module _escape

    Public Function unescape(ByVal src As String, ByRef dst As String) As Boolean
        If src Is Nothing Then
            Return False
        Else
            Dim i As Int32
            Dim other As Char
            Dim rtn As StringBuilder = Nothing
            rtn = New StringBuilder(convertor.toint32(strlen(src)))
            For i = 0 To strlen(src) - 1
                If src(i) = character.rightSlash AndAlso i + 1 < strlen(src) Then
                    Select Case Char.ToLower(src(i + 1))
                        Case character.t
                            other = character.tab
                        Case character.r
                            other = character.return
                        Case character.n
                            other = character.newline
                        Case character.rightSlash
                            other = character.rightSlash
                        Case character.b
                            other = character.backspace
                        Case character.f
                            other = character.feed
                        Case character.v
                            other = character.vtab
                        Case character.x
                            If i + 2 < strlen(src) AndAlso ishexdigit(src(i + 2)) Then
                                If i + 3 < strlen(src) AndAlso ishexdigit(src(i + 3)) Then
#If Not (PocketPC OrElse Smartphone) Then
                                    other = Chr(Convert.ToInt32(StrConv(strmid(src, i + 2, 2), VbStrConv.Narrow _
                                                                        , localeID.zh_cn), 16))
#Else
                                    Dim chars As Int32
                                    convertor.toint32(strmid(src, i + 2, 2), chars, 16)
                                    other = Chr(chars)
#End If
                                    i += 2
                                Else
#If Not (PocketPC OrElse Smartphone) Then
                                    other = Chr(Convert.ToInt32(StrConv(strmid(src, i + 2, 1), VbStrConv.Narrow _
                                                                        , localeID.zh_cn), 16))
#Else
                                    Dim chars As Int32
                                    convertor.toint32(strmid(src, i + 2, 1), chars, 16)
                                    other = Chr(chars)
#End If
                                    i += 1
                                End If
                            Else
                                other = character.null
                            End If
                        Case Else
                            If isdigit(src(i + 1)) Then
                                If i + 2 < strlen(src) AndAlso isdigit(src(i + 2)) Then
                                    If i + 3 < strlen(src) AndAlso isdigit(src(i + 3)) Then
#If Not (PocketPC OrElse Smartphone) Then
                                        other = Chr(Convert.ToInt32(StrConv(strmid(src, i + 1, 3), VbStrConv.Narrow _
                                                                            , localeID.zh_cn)))
#Else
                                        Dim chars As Int32
                                        convertor.toint32(strmid(src, i + 1, 3), chars)
                                        other = Chr(chars)
#End If
                                        i += 2
                                    Else
#If Not (PocketPC OrElse Smartphone) Then
                                        other = Chr(Convert.ToInt32(StrConv(strmid(src, i + 1, 2), VbStrConv.Narrow _
                                                                            , localeID.zh_cn)))
#Else
                                        Dim chars As Int32
                                        convertor.toint32(strmid(src, i + 1, 2), chars)
                                        other = Chr(chars)
#End If
                                        i += 1
                                    End If
                                Else
#If Not (PocketPC OrElse Smartphone) Then
                                    other = Chr(Convert.ToInt32(StrConv(strmid(src, i + 1, 1), VbStrConv.Narrow _
                                                                        , localeID.zh_cn)))
#Else
                                    Dim chars As Int32
                                    convertor.toint32(strmid(src, i + 1, 1), chars)
                                    other = Chr(chars)
#End If
                                End If
                            Else
                                other = character.rightSlash
                                i -= 1
                            End If
                    End Select
                    i += 1
                Else
                    other = src(i)
                End If

                rtn.Append(other)
            Next

            dst = Convert.ToString(rtn)
            Return True
        End If
    End Function

    Public Function escape(ByVal src As String, ByRef dst As String) As Boolean
        If src Is Nothing Then
            Return False
        Else
            Dim i As Int32
            Dim rtn As StringBuilder = Nothing
            rtn = New StringBuilder(convertor.toint32(strlen(src)) << 1)
            For i = 0 To strlen(src) - 1
                Select Case src(i)
                    Case character.tab
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.t)
                    Case character.return
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.r)
                    Case character.newline
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.n)
                    Case character.rightSlash
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.rightSlash)
                    Case character.vtab
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.v)
                    Case character.feed
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.f)
                    Case character.backspace
                        rtn.Append(character.rightSlash)
                        rtn.Append(character.b)
                    Case Else
                        rtn.Append(src(i))
                End Select
            Next
            dst = Convert.ToString(rtn)

            Return True
        End If
    End Function

    Public Function escapeBack(ByVal src As String, ByRef dst As String) As Boolean
        Return unescape(src, dst)
    End Function

    Public Function escape(ByRef src As String) As String
        Dim dst As String = Nothing
        If escape(src, dst) Then
            copy(src, dst)
            Return src
        Else
            Return Nothing
        End If
    End Function

    Public Function escape_unref(ByVal src As String) As String
        Dim dst As String = Nothing
        If escape(src, dst) Then
            Return dst
        Else
            Return Nothing
        End If
    End Function

    Public Function unescape(ByRef src As String) As String
        Dim dst As String = Nothing
        If unescape(src, dst) Then
            copy(src, dst)
            Return src
        Else
            Return Nothing
        End If
    End Function

    Public Function unescape_unref(ByVal src As String) As String
        Dim dst As String = Nothing
        If unescape(src, dst) Then
            Return dst
        Else
            Return Nothing
        End If
    End Function

    Public Function escapeBack(ByRef src As String) As String
        Return unescape(src)
    End Function

    Public Function escapeBack_unref(ByVal src As String) As String
        Return unescape_unref(src)
    End Function
End Module
